package pl.koszolko.documentclustering.ui;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Collections;
import java.util.List;
import java.util.Properties;
import java.util.Scanner;

import org.apache.log4j.PropertyConfigurator;

import pl.koszolko.documentclustering.cluster.Cluster;
import pl.koszolko.documentclustering.cluster.ClusteringAlgorithm;
import pl.koszolko.documentclustering.cluster.ClusteringAlgorithmAgglomerative;
import pl.koszolko.documentclustering.cluster.Dendrogram;
import pl.koszolko.documentclustering.cluster.document.DocumentForClustering;
import pl.koszolko.documentclustering.cluster.document.FactoryDocumentForClustering;
import pl.koszolko.documentclustering.procesmanager.task.CrawlerProcessorMultithread;
import pl.koszolko.documentclustering.ui.dendrogram.DendrogramDrawer;
import pl.koszolko.documentclustering.ui.dendrogram.DendrogramSaver;

public class SimpleTextUI {
	private static final Object ABSTRACT = "-a";
	private static final Object REFERENCES = "-r";
	private static final Object CITED = "-c";

	private static String PROPERTIES_FILE = "dbConfig.properties";

	private static String HOST = "host";
	private static String USER = "user";
	private static String PASSWORD = "password";

	private static ClusteringAlgorithm algorithm;
	private static List<DocumentForClustering> documents;
	private static DendrogramDrawer saver;
	private static DendrogramSaver drawer;
	private static CrawlerProcessorMultithread crawlerProcessor;

	static {
		saver = new DendrogramDrawer();
		drawer = new DendrogramSaver();
		crawlerProcessor = new CrawlerProcessorMultithread();
		algorithm = new ClusteringAlgorithmAgglomerative();

		PropertyConfigurator.configure("config" + File.separator
				+ "log4j.properties");
	}

	public static void main(String[] args) {
		// pobranie pozycji na ktorej moze znajdowac sie opcja -I
		int indexI = checkIsImport(args);
		if (indexI != -1) {
			System.out.println("ROZPOCZYNAM IMPORT DOKUMENTOW");
			// wykonanie tylko importu plikow
			// pobranie sciezki do pliku z id artykulow do pobrania
			if (args.length <= indexI + 1) {
				System.out.println("Brak pliku z identyfikatorami !");
				return;
			}

			String file = args[++indexI];

			if (file == null) {
				System.out
						.println("Brak nazwy pliku z identyfikatorami artykulow");
				return;
			}
			// pobranie ustawien bazy danych
			Properties properties;
			try {
				properties = loadProperties();
			} catch (Exception e) {
				System.out.println("Blad odczytu konfiguracji bazy danych");
				return;
			}

			String host = properties.getProperty(HOST);
			String user = properties.getProperty(USER);
			String password = properties.getProperty(PASSWORD);

			crawlerProcessor.createConnectionManager(host, user, password);
			List<String> documentsIds = crawlerProcessor
					.getDocumentIdsFromFile(file);
			crawlerProcessor.saveDocuments(documentsIds);
			System.out.println("Import zakonczony");
			return;
		}

		String clusteringOption = getClusteringOption(args);
		if (clusteringOption != null) {
			documents = getDocumentsByClusteringOption(clusteringOption);
		} else {
			printMenu();
			switch (readClusteringOption()) {
			case 1:
				documents = FactoryDocumentForClustering.getInstace()
						.createDocumentForClusteringByAbstract();
				break;
			case 2:
				documents = FactoryDocumentForClustering.getInstace()
						.createDocumentForClusteringByReferences();
				break;
			case 3:
				documents = FactoryDocumentForClustering.getInstace()
						.createDocumentForClusteringByCitedBy();
				break;
			case 4:
				documents = FactoryDocumentForClustering.getInstace()
						.createDocumentForClusteringByAuthor();
				break;
			case 5:
				documents = FactoryDocumentForClustering.getInstace()
						.createDocumentForClusteringBySoundexAuthor();
				break;
			case 6:
				documents = FactoryDocumentForClustering.getInstace()
						.createDocumentForCLusteringByReferencesAndCitedBy();
				break;
			default:
				printError();
				return;
			}
		}

		Dendrogram dendrogram = algorithm.hierarchicalClustering(documents);
		printResults(dendrogram);
		printFinalClusters(dendrogram);
		//saveResults(dendrogram);
	}

	private static void printFinalClusters(Dendrogram dendrogram) {
		List<Cluster> finalClusters = dendrogram.getClustersToMarge();
		int i=0;
		for(Cluster cluster : finalClusters) {
			System.out.println("\nGrupa " + i++);
			System.out.println("Liczba dokumentow: " + cluster.getDocuments().size());
			System.out.println("Dokumenty:");
//			for(DocumentForClustering doc : cluster.getDocuments()) {
//				System.out.println(doc.getTitle());
//			}
		}
		
	}

	private static List<DocumentForClustering> getDocumentsByClusteringOption(
			String clusteringOption) {
		if (clusteringOption.equals(ABSTRACT)) {
			return FactoryDocumentForClustering.getInstace()
					.createDocumentForClusteringByAbstract();
		} else if (clusteringOption.equals(REFERENCES)) {
			return FactoryDocumentForClustering.getInstace()
					.createDocumentForClusteringByReferences();
		} else if (clusteringOption.equals(CITED)) {
			return FactoryDocumentForClustering.getInstace()
					.createDocumentForClusteringByCitedBy();
		}
		return null;
	}

	private static String getClusteringOption(String[] args) {
		for (String arg : args) {
			if (arg.equals(ABSTRACT) || arg.equals(REFERENCES)
					|| arg.equals(CITED)) {
				return arg;
			}
		}
		return null;
	}

	private static Properties loadProperties() throws FileNotFoundException,
			IOException {
		Properties properties = new Properties();

		properties.load(new FileInputStream("config" + File.separator
				+ PROPERTIES_FILE));

		return properties;
	}

	private static int checkIsImport(String[] args) {
		for (int i = 0; i < args.length; ++i) {
			if (args[i].equals("-I")) {
				return i;
			}
		}
		return -1;
	}

	private static void saveResults(Dendrogram dendrogram) {
		saver.prepareDendrogramToDraw(dendrogram);
		drawer.saveDendrogramToFile("dendrogram", saver);
	}

	private static void printResults(Dendrogram dendrogram) {
		List<String> clustersNames = saver.setLabelsForNodes(dendrogram);
		Collections.sort(clustersNames, Collections.reverseOrder());
		for (String s : clustersNames) {
			System.out.println(s);
		}
	}

	private static void printError() {
		System.out.println("Blad przy czytaniu odpowiedzi. Zamykam aplikacje");
	}

	private static int readClusteringOption() {
		int clusteringOption = -1;
		try {
			Scanner in = new Scanner(System.in);

			clusteringOption = in.nextInt();
			in.close();
		} catch (Exception e) {
			clusteringOption = -1;
		}

		return clusteringOption;
	}

	private static void printMenu() {
		System.out
				.println("Aplikacja pozwala na grupowanie artykulow naukowych zapisanych w bazie danych");
		System.out.println("Wybierz sposob grupowania");
		System.out.println("1. Grupowanie po abstraktach");
		System.out.println("2. Grupowanie po liscie cytowan");
		System.out.println("3. Grupowanie po liscie artykulow cytujacych");
		System.out.println("4. Grupowanie po autorach");
		System.out.println("5. Grupowanie po autorach (soundex)");
		System.out.println("6. Grupowanie po liscie cytowan i liscie artykulow cytujacych");
	}
}
